<?php

use App\Facades\Sigma;

/**
 * Notes   : 隐藏字符串中间的N位
 *
 * @Date   : 2023/7/19 15:12
 * @Author : <Jason.C>
 * @param  string  $mobile  手机号
 * @param  int  $len  隐藏位数
 * @param  string  $char  填充符号
 * @return string
 */
function hideMobilePhoneNo(string $mobile, int $len = 4, string $char = '*'): string
{
    if ($len >= strlen($mobile)) {
        $len = ceil(strlen($mobile) / 2);
    }
    $fill = str_repeat($char, $len);

    $residue = strlen($mobile) - $len;

    return substr($mobile, 0, intval($residue / 2)).$fill.substr($mobile, -ceil($residue / 2));
}

/**
 * 数组转换为树型结构，用于无限极分类
 *
 * @param  array  $list
 * @param  int  $parentId
 * @param  string  $parentNodeName
 * @param  string  $primaryKey
 * @param  string  $childNodeName
 * @return array
 */
function array2tree(
    array $list,
    int $parentId = 0,
    string $primaryKey = 'id',
    string $parentNodeName = 'parent_id',
    string $childNodeName = 'children'
): array {
    $resultArr = [];
    if (empty($list)) {
        return [];
    }
    foreach ($list as $key => $item) {
        if ($item[$parentNodeName] == $parentId) {
            unset($list[$key]);
            $item[$childNodeName] = array2tree(
                $list,
                $item[$primaryKey],
                $primaryKey,
                $parentNodeName,
                $childNodeName
            );
            $resultArr[$key] = $item;
        }
    }

    return $resultArr;
}

/**
 * Notes   : 无限级分类2
 *           这个速度要比递归稳定一些
 *
 * @Date   : 2023/7/5 10:48
 * @Author : <Jason.C>
 * @param  array  $list
 * @param  int  $parentId
 * @param  string  $primaryKey
 * @param  string  $parentNodeName
 * @param  string  $childNodeName
 * @return array
 */
function list2tree(
    array $list,
    string $primaryKey = 'id',
    string $parentNodeName = 'parent_id',
    string $childNodeName = 'children',
    int $parentId = 0
): array {
    $tree = [];
    $refer = [];
    foreach ($list as $key => $data) {
        $refer[$data[$primaryKey]] = &$list[$key];
    }
    foreach ($list as $key => $data) {
        $pid = $data[$parentNodeName];
        if ($parentId == $pid) {
            $tree[] = &$list[$key];
        } elseif (isset($refer[$pid])) {
            $parent = &$refer[$pid];
            $parent[$childNodeName][] = &$list[$key];
        }
    }

    return $tree;
}

/**
 * Notes   : 创建订单编号
 *
 * @Date   : 2023/7/25 09:30
 * @Author : <Jason.C>
 * @param  string  $prefix  编号前缀
 * @param  int  $length
 * @return string
 * @throws Exception
 */
function createOrderNo(string $prefix = '', int $length = 18): string
{
    if ($length <= 13 || $length > 24) {
        throw new RuntimeException('数字长度必须大于13位且小于24位');
    }
    $rand = $length - 13;

    $time = explode(' ', microtime());
    $no = date('ymdHis').sprintf("%0{$rand}d", $time[0] * (10 ** $rand));

    return $prefix.Sigma::orderNo($no);
}

/**
 * Notes   : 格式化字节大小
 *
 * @Date   : 2023/8/1 17:37
 * @Author : <Jason.C>
 * @param  int  $size
 * @return string
 */
function formatBytes(int $size): string
{
    $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];

    for ($i = 0; $size >= 1024 && $i < 5; $i++) {
        $size /= 1024;
    }

    return round($size, 2).$units[$i];
}

/**
 * Notes   : 获取两个经纬度之间的距离
 *
 * @Date   : 2023/12/26 21:53
 * @Author : <Jason.C>
 * @param  float  $lat1  A点经度
 * @param  float  $lng1  A点纬度
 * @param  float  $lat2  B点经度
 * @param  float  $lng2  B点纬度
 * @param  float  $earthRadius  [6371]地球平均曲率半径；[6378.137]经度系数，1米所对应的经度为0.000011；[6370.996]地球半径系数
 * @return float  两点之间的距离，单位m
 */
function calculateDistance1(float $lat1, float $lng1, float $lat2, float $lng2, float $earthRadius = 6371): float
{
    $radLat1 = deg2rad($lat1);
    $radLat2 = deg2rad($lat2);
    $a = $radLat1 - $radLat2;
    $b = deg2rad($lng1) - deg2rad($lng2);
    $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
    $s = $s * $earthRadius * 1000;

    return round($s, 2);
}
